一、简单数据类型 1.声明变量特殊情况
情况
说明
结果
var age ; console.log (age);
只声明 不赋值
undefined
console.log(age);
不声明 不赋值 直接使用
报错
age = 10; console.log (age);
不声明 只赋值
10
2.Undefined 和 Null 一个声明后没有被赋值的变量会有一个默认值 undefined ( 如果进行相连或者相加时,注意结果)
1 2 3 4 5 var variable;console .log(variable); console .log('你好' + variable); console .log(11 + variable); console .log(true + variable);
一个声明变量给 null 值,里面存的值为空(学习对象时,我们继续研究null)
1 2 3 console .log('你好' + vari); console .log(11 + vari); console .log(true + vari);
3.数据类型转换 使用表单、prompt 获取过来的数据默认是字符串类 型的,此时就不能直接简单的进行加法运算,而需要转换变 量的数据类型。通俗来说,就是把一种数据类型的变量转换成另外一种数据类型。
我们通常会实现3种方式的转换:
转换为字符串类型:变量.toString() String(变量) 变量 + ‘‘
转换为数字型:parseInt(变量) parseFloat(变量) Number(变量) 利用算数运算 - * / 隐式转换
转换为布尔型:Boolean(变量)
二、函数 1.形参和实参 在JavaScript中,形参的默认值是undefined。
实参个数多于形参,只取到形参的个数
实参个数少于形参,多的形参定义为undefined,结果为NaN
2.return 语句 如果函数没有 return ,返回的值是 undefined
return 语句之后的代码不被执行。
return 只能返回一个值 。如果用逗号隔开多个值,以最后一个为准。
如果没有return 则返回 undefined
3.arguments 的使用 只有函数才有 arguments对象 而且是每个函数都内置好了这个arguments
1 2 3 4 5 6 7 8 9 10 11 function fn ( ) { for (var i = 0 ; i < arguments .length; i++) { console .log(arguments [i]); } } fn(1 , 2 , 3 ); fn(1 , 2 , 3 , 4 , 5 );
4.伪数组 并不是真正意义上的数组
具有数组的 length 属性
按照索引的方式进行存储的
它没有真正数组的一些方法 pop() push() 等等
5.函数的两中声明方式
利用函数关键字自定义函数(命名函数)
函数表达式(匿名函数) 1 2 3 4 5 6 7 8 var 变量名 = function ( ) {};变量名(); var fun = function (aru ) { console .log('我是函数表达式' ); console .log(aru); } fun('hello world' );
(1) fun是变量名 不是函数名
(2) 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数
(3) 函数表达式也可以进行传递参数
6.变量的作用域 如果在函数内部 没有声明直接赋值 的变量也属于全局变量
1 2 3 function fun (aru ) { num = 20 ; }
7.预解析(面试考点) js引擎运行js 分为两步
(1). 预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
(2). 代码执行 按照代码书写的顺序从上往下执行
预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
(1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
因此 函数表达式 调用必须写在函数表达式的下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 console .log(num); var num = 10 ;fun(); var fun = function ( ) { console .log(22 ); }
(2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
1 2 3 4 5 6 7 8 9 fn(); function fn ( ) { console .log(11 ); }
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 f1(); console .log(c);console .log(b);console .log(a);function f1 ( ) { var a = b = c = 9 ; console .log(a); console .log(b); console .log(c); }
三、对象 1.对象创建方法 利用对象字面量创建对象
1 2 3 4 5 6 7 8 9 10 11 12 13 var obj = { uname: '张三疯' , age: 18 , sex: '男' , sayHi: function ( ) { console .log('hi~' ); } } console .log(obj.uname);console .log(obj['age' ]);obj.sayHi();
利用 new Object 创建对象
1 2 3 4 5 6 7 8 9 10 11 var obj = new Object (); obj.uname = '张三疯' ; obj.age = 18 ; obj.sex = '男' ; obj.sayHi = function ( ) { console .log('hi~' ); } console .log(obj.uname);console .log(obj['sex' ]);obj.sayHi();
利用构造函数创建对象
构造函数名字首字母要大写
构造函数不需要return 就可以返回结果
构造函数的属性和方法前面必须添加 this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function Star (uname, age, sex ) { this .name = uname; this .age = age; this .sex = sex; this .sing = function (song ) { console .log(song); } } var ldh = new Star('刘德华' , 18 , '男' ); console .log(ldh.name);console .log(ldh['sex' ]);ldh.sing('冰雨' ); var zxy = new Star('张学友' , 19 , '男' );console .log(zxy.name);console .log(zxy.age);zxy.sing('李香兰' )
2.new关键字执行过程
new 构造函数可以在内存中创建了一个空的对象
this 就会指向刚才创建的空对象
执行构造函数里面的代码 给这个空对象添加属性和方法
返回这个对象
3.遍历对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var obj = { name: 'pink老师' , age: 18 , sex: '男' , fn: function ( ) {} } for (var k in obj) { console .log(k); console .log(obj[k]); }
4.内置对象 Math对象
Math数学对象不是一个构造函数 ,所以不需要new 来调用 而是直接使用里面的属性和方法即可
1 2 3 4 5 6 7 8 9 10 11 12 Math .PI Math .floor() Math .ceil() Math .round() Math .abs() Math .max() Math .min() Math .random() function getRandom (min, max ) { return Math .floor(Math .random() * (max - min + 1 )) + min; }
Date对象
Date对象是一个构造函数 必须使用new 来调用创建我们的日期对象
1 2 3 4 5 6 7 8 var date = new Date ();console .log(date);var date1 = new Date (2021 , 10 , 1 );console .log(date1); var date2 = new Date ('2021-10-1 8:8:8' );console .log(date2);
格式化日期 年月日
1 2 3 4 5 6 7 8 9 10 11 12 var date = new Date ();console .log(date.getFullYear()); console .log(date.getMonth() + 1 ); console .log(date.getDate()); console .log(date.getDay()); var year = date.getFullYear();var month = date.getMonth() + 1 ;var dates = date.getDate();var arr = ['星期日' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六' ];var day = date.getDay();console .log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);
格式化日期 时分秒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var date = new Date ();console .log(date.getHours()); console .log(date.getMinutes()); console .log(date.getSeconds()); function getTimer ( ) { var time = new Date (); var h = time.getHours(); h = h < 10 ? '0' + h : h; var m = time.getMinutes(); m = m < 10 ? '0' + m : m; var s = time.getSeconds(); s = s < 10 ? '0' + s : s; return h + ':' + m + ':' + s; } console .log(getTimer());
获得Date总的毫秒数(时间戳) 不是当前时间的毫秒数 而是距离1970年1月1号过了多少毫秒数
1 2 3 4 5 6 7 8 9 var date = new Date ();console .log(date.valueOf()); console .log(date.getTime());var date1 = +new Date (); console .log(date1);console .log(Date .now());
倒计时效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function countDown (time ) { var nowTime = +new Date (); var inputTime = +new Date (time); var times = (inputTime - nowTime) / 1000 ; var d = parseInt (times / 60 / 60 / 24 ); d = d < 10 ? '0' + d : d; var h = parseInt (times / 60 / 60 % 24 ); h = h < 10 ? '0' + h : h; var m = parseInt (times / 60 % 60 ); m = m < 10 ? '0' + m : m; var s = parseInt (times % 60 ); s = s < 10 ? '0' + s : s; return d + '天' + h + '时' + m + '分' + s + '秒' ; } console .log(countDown('2019-5-1 18:00:00' ));var date = new Date ();console .log(date);
四、数组 1.创建数组的两种方式 1 2 3 4 5 6 7 8 9 var arr = [1 , 2 , 3 ];console .log(arr[0 ]);var arr1 = new Array (2 , 3 ); console .log(arr1);
在同一个数组中可以存放任意的数据类型
如:var arr1 = [1, 2, ‘ test’, true];
2.新增数组元素 修改length长度 1 2 3 4 5 6 var arr = ['red' , 'green' , 'blue' ];console .log(arr.length);arr.length = 5 ; console .log(arr);console .log(arr[3 ]); console .log(arr[4 ]);
数组长度可以自动检测里面元素变化
3.冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 var arr = [4 , 1 , 2 , 3 , 5 ];for (var i = 0 ; i <= arr.length - 1 ; i++) { for (var j = 0 ; j <= arr.length - i - 1 ; j++) { if (arr[j] < arr[j + 1 ]) { var temp = arr[j]; arr[j] = arr[j + 1 ]; arr[j + 1 ] = temp; } } } console .log(arr);
4.检测是否为数组 1 2 3 4 5 6 7 8 var arr = [];var obj = {};console.log(arr instanceof Array); console.log(obj instanceof Array); console.log(Array.isArray(arr)); console.log(Array.isArray(obj));
5.添加删除数组元素的方法
push() 在我们数组的末尾 添加一个或者多个数组元素 1 2 3 4 5 6 7 8 var arr = [1 , 2 , 3 ];console .log(arr.push(4 , 'pink' ));console .log(arr);
unshift() 在数组的开头 添加一个或者多个数组元素1 2 3 4 5 6 console .log(arr.unshift('red' , 'purple' ));console .log(arr);
pop() 可以删除数组的最后一个 元素 1 2 3 4 5 6 console .log(arr.pop());console .log(arr);
shift() 可以删除数组的第一个 元素 1 2 3 4 5 6 console .log(arr.shift());console .log(arr);
案例 :筛选数组
1 2 3 4 5 6 7 8 9 10 var arr = [1500 , 1200 , 2000 , 2100 , 1800 ];var newArr = [];for (var i = 0 ; i < arr.length; i++) { if (arr[i] < 2000 ) { newArr.push(arr[i]); } } console .log(newArr);
6.翻转数组 1 2 3 var arr = ['pink' , 'red' , 'blue' ];arr.reverse(); console .log(arr);
7.数组排序 1 2 3 4 5 6 7 var arr1 = [13 , 4 , 77 , 1 , 7 ];arr1.sort(function (a, b ) { return b - a; }); console .log(arr1);
8.获取数组元素索引 1 2 3 4 5 6 7 8 var arr = ['red' , 'green' , 'pink' ];console .log(arr.indexOf('blue' ));var arr = ['red' , 'green' , 'blue' , 'pink' , 'blue' ];console .log(arr.lastIndexOf('blue' ));
案例 :数组去重(面试考点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function unique (arr ) { var newArr = []; for (var i = 0 ; i < arr.length; i++) { if (newArr.indexOf(arr[i]) === -1 ) { newArr.push(arr[i]); } } return newArr; } var demo = unique(['c' , 'a' , 'z' , 'a' , 'x' , 'a' , 'x' , 'c' , 'b' ])console .log(demo);
9.数组转换为字符串 1 2 3 4 5 6 7 8 var arr = [1 , 2 , 3 ];console .log(arr.toString()); var arr1 = ['green' , 'blue' , 'pink' ];console .log(arr1.join()); console .log(arr1.join('-' )); console .log(arr1.join('&' ));
五、字符串 1.基本包装类型 为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。 基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。
1 2 3 4 5 6 7 8 9 var str = 'andy' ; console .log(str.length);var temp = new String ('andy' );str = temp; temp = null ;
2.字符串的不可变 指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
1 2 3 4 5 6 7 8 9 var str = 'abc' ;str = 'hello' ; var str = '' ;for (var i = 0 ; i < 100000 ; i++) { str += i; } console .log(str);
3.根据字符返回位置 1 2 3 4 var str = '改革春风吹满地,春天来了' ;console .log(str.indexOf('春' ));console .log(str.indexOf('春' , 3 ));
案例 :查找字符串中某个字符出现的位置以及次数(面试考点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var str = "oabcoefoxyozzopp" ;var index = str.indexOf('o' );var num = 0 ;while (index !== -1 ) { console .log(index); num++; index = str.indexOf('o' , index + 1 ); } console .log('o出现的次数是: ' + num);
4.根据位置返回字符 1 2 3 4 5 6 7 8 9 10 11 var str = 'andy' ;console .log(str.charAt(3 ));for (var i = 0 ; i < str.length; i++) { console .log(str.charAt(i)); } console .log(str.charCodeAt(0 )); console .log(str[0 ]);
案例 :判断一个字符串中出现次数最多的字符,并统计其次数(面试考点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 var o = { age: 18 } if (o['sex' ]) { console .log('里面有该属性' ); } else { console .log('没有该属性' ); } var str = 'abcoefoxyozzopp' ;var o = {};for (var i = 0 ; i < str.length; i++) { var chars = str.charAt(i); if (o[chars]) { o[chars]++; } else { o[chars] = 1 ; } } console .log(o);var max = 0 ;var ch = '' ;for (var k in o) { if (o[k] > max) { max = o[k]; ch = k; } } console .log(max);console .log('最多的字符是' + ch);
5.字符串操作方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var str = 'andy' ;console .log(str.concat('red' ));var str1 = '改革春风吹满地' ;console .log(str1.substr(2 , 2 )); var str = 'andyandy' ;console .log(str.replace('a' , 'b' ));var str1 = 'abcoefoxyozzopp' ;while (str1.indexOf('o' ) !== -1 ) { str1 = str1.replace('o' , '*' ); } console .log(str1);var str2 = 'red,pink,blue' ;console .log(str2.split(',' ));var str3 = 'red&pink&blue' ;console .log(str3.split('&' ));
六、简单数据类型与复杂数据类型 1.基本概念 简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
值类型:简单数据类型/基本数据类型 ,在存储时变量中存储的是值本身,因此叫做值类型。包括string ,number,boolean,undefined,null
引用类型:复杂数据类型 ,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
注意:简单数据类型 null 返回的是一个空的对象 object
1 2 var timer = null ;console .log(typeof timer);
2.内存分配
简单数据类型 :存放在栈里面 里面直接开辟一个空间存放的是值
复杂数据类型 :首先在栈里面存放地址 十六进制表示 然后这个地址指向堆里面的数据 真正的对象实例存放在堆空间中
3.参数传递
简单数据类型 :函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈 空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
复杂数据类型 :函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地 址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。